package main

/*

#include <stdlib.h>
#include <dlfcn.h>
*/
import "C"
import (
	"unsafe"
)

type Error struct {
	Message string
}

func (err *Error) Error() string {
	return err.Message
}

func dlopen(path string) (lib unsafe.Pointer, err error) {
	var f = C.int(C.RTLD_NOW | C.RTLD_LOCAL)
	var s *C.char

	if lib = C.dlopen(s, f); lib == nil {
		err = dlerror()
	}

	return
}

func dlclose(lib unsafe.Pointer) (err error) {

	if C.dlclose(lib) != 0 {
		err = dlerror()
	}

	return
}

func dlsym(lib unsafe.Pointer, name string) (addr unsafe.Pointer, err error) {
	var s = C.CString(name)
	defer C.free(unsafe.Pointer(s))

	if addr = C.dlsym(lib, s); addr == nil {
		err = dlerror()
	}

	return
}

func dlerror() error {
	return &Error{
		Message: C.GoString(C.dlerror()),
	}
}
